<!DOCTYPE html>
<html lang="zh">

<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
	<meta name="keywords" content="dromara.org" />
	<meta name="description" content="dromara.org" />
	<!-- 网页标签标题 -->
	<title>dromara(Open source organization)</title>
	<link rel="shortcut icon" href="/website/img/docsite.ico"/>
	<link rel="stylesheet" href="/website/build/documentation.css" />
</head>
<body>
	<div id="root"><div class="documentation-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/website/zh-cn/index.html"><img class="logo" src="/website/img/dromara.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/website/img/system/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a href="/website/zh-cn/index.html" target="_self">首页</a><div class="sub-menu"><ul></ul></div></li><li class="menu-item menu-item-normal menu-item-normal-active"><a href="#">文档</a><div class="sub-menu"><ul><li><a href="/website/zh-cn/docs/soul/soul.html" target="_self">Soul</a></li><li><a href="/website/zh-cn/docs/hmily/index.html" target="_self">Hmily</a></li></ul></div></li><li class="menu-item menu-item-normal"><a href="/website/zh-cn/blog/index.html" target="_self">博客</a><div class="sub-menu"><ul></ul></div></li><li class="menu-item menu-item-normal"><a href="/website/zh-cn/community/index.html" target="_self">社区</a><div class="sub-menu"><ul></ul></div></li></ul></div></div></header><section class="content-section"><div class="sidemenu" id="menu"><div class="sidemenu-toggle"><img src="https://img.alicdn.com/tfs/TB1E6apXHGYBuNjy0FoXXciBFXa-200-200.png"/></div><ul><li class="menu-item menu-item-level-1"><span>Soul</span><ul><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><a href="/website/zh-cn/docs/soul/soul.html" target="_self">soul介绍</a></li><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><a href="/website/zh-cn/docs/soul/team.html" target="_self">团队介绍</a></li><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><a href="/website/zh-cn/docs/soul/induction.html" target="_self">soul极简入门</a></li><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><a href="/website/zh-cn/docs/soul/db.html" target="_self">数据库设计</a></li><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><a href="/website/zh-cn/docs/soul/config.html" target="_self">数据配置流程</a></li><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><a href="/website/zh-cn/docs/soul/dataSync.html" target="_self">数据同步原理</a></li><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><a href="/website/zh-cn/docs/soul/metaData.html" target="_self">元数据概念介绍</a></li><li style="height:684px;overflow:hidden" class="menu-item menu-item-level-2"><span>用户使用文档<img style="transform:rotate(0deg)" class="menu-toggle" src="/website/img/system/arrow_down.png"/></span><ul><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/setup.html" target="_self">搭建soul网关环境</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/user-http.html" target="_self">http用户</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/user-dubbo.html" target="_self">dubbo用户</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/user-springcloud.html" target="_self">springCloud用户</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/user-sofa.html" target="_self">sofa用户</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/selector.html" target="_self">选择器规则详解</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/user-dataSync.html" target="_self">数据同步策略</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-divide.html" target="_self">divide插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-dubbo.html" target="_self">dubbo插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-springcloud.html" target="_self">springcloud插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-sofa.html" target="_self">sofa插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-rateLimiter.html" target="_self">rateLimiter插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-hystrix.html" target="_self">hystrix插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-monitor.html" target="_self">monitor插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-waf.html" target="_self">waf插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-sign.html" target="_self">sign插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-rewrite.html" target="_self">rewrite插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-websocket.html" target="_self">websocket支持</a></li></ul></li><li style="height:360px;overflow:hidden" class="menu-item menu-item-level-2"><span>开发者文档<img style="transform:rotate(0deg)" class="menu-toggle" src="/website/img/system/arrow_down.png"/></span><ul><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/dev-filter.html" target="_self">自定义filter</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/dev-plugin.html" target="_self">自定义插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/dev-file.html" target="_self">文件上传下载</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/dev-iphost.html" target="_self">自定义解析IP与host</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/dev-result.html" target="_self">自定义返回结果</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/dev-sign.html" target="_self">自定义签名插件算法与验证</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/dev-client.html" target="_self">多语言http客户端接入</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/dev-thread.html" target="_self">线程模型</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/dev-netty.html" target="_self">soul调优</a></li></ul></li><li style="height:144px;overflow:hidden" class="menu-item menu-item-level-2"><span>社区贡献<img style="transform:rotate(0deg)" class="menu-toggle" src="/website/img/system/arrow_down.png"/></span><ul><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/contributor.html" target="_self">贡献者指南</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/committer.html" target="_self">提交者指南</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/code-conduct.html" target="_self">编码规范</a></li></ul></li></ul></li></ul></div><div class="doc-content markdown-body" id="doc-body"><h2>说明</h2>
<ul>
<li>
<p>插件是 soul 网关的核心执行者，每个插件在开启的情况下，都会对匹配的流量，进行自己的处理。</p>
</li>
<li>
<p>在soul 网关里面，插件其实分为2 类：</p>
<ul>
<li>
<p>一类是单一职责的调用链，不能对流量进行自定义的筛选。</p>
</li>
<li>
<p>另一类，能对匹配的流量，执行自己的职责调用链。</p>
</li>
</ul>
</li>
<li>
<p>用户可以参考 soul-plugin 模块，新增自己的插件处理，如果有好的公用插件，请把代码提交上来。</p>
</li>
</ul>
<h2>单一职责插件</h2>
<ul>
<li>引入如下依赖 :</li>
</ul>
<pre><code> &lt;dependency&gt;
        &lt;groupId&gt;org.dromara&lt;/groupId&gt;
        &lt;artifactId&gt;soul-plugin-api&lt;/artifactId&gt;
        &lt;version&gt;${last.version}&lt;/version&gt;
  &lt;/dependency&gt;
</code></pre>
<ul>
<li>用户新增一个类 A,直接实现 <code>org.dromara.soul.plugin.api.SoulPlugin</code></li>
</ul>
<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">SoulPlugin</span> </span>{

    <span class="hljs-comment">/**
     * Process the Web request and (optionally) delegate to the next
     * {<span class="hljs-doctag">@code</span> WebFilter} through the given {<span class="hljs-doctag">@link</span> SoulPluginChain}.
     *
     * <span class="hljs-doctag">@param</span> exchange the current server exchange
     * <span class="hljs-doctag">@param</span> chain    provides a way to delegate to the next filter
     * <span class="hljs-doctag">@return</span> {<span class="hljs-doctag">@code</span> Mono&lt;Void&gt;} to indicate when request processing is complete
     */</span>
    <span class="hljs-function">Mono&lt;Void&gt; <span class="hljs-title">execute</span><span class="hljs-params">(ServerWebExchange exchange, SoulPluginChain chain)</span></span>;

    <span class="hljs-comment">/**
     * return plugin order .
     * This attribute To determine the plugin execution order in the same type plugin.
     *
     * <span class="hljs-doctag">@return</span> int order
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">getOrder</span><span class="hljs-params">()</span></span>;

    <span class="hljs-comment">/**
     * acquire plugin name.
     * this is plugin name define you must Provide the right name.
     * if you impl AbstractSoulPlugin this attribute not use.
     *
     * <span class="hljs-doctag">@return</span> plugin name.
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">default</span> String <span class="hljs-title">named</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> <span class="hljs-string">""</span>;
    }

    <span class="hljs-comment">/**
     * plugin is execute.
     * if return true this plugin can not execute.
     *
     * <span class="hljs-doctag">@param</span> exchange the current server exchange
     * <span class="hljs-doctag">@return</span> default false.
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">default</span> Boolean <span class="hljs-title">skip</span><span class="hljs-params">(ServerWebExchange exchange)</span> </span>{
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;
    }
}

</code></pre>
<ul>
<li>
<p>接口方法详细说明</p>
<ul>
<li>
<p><code>execute()</code> 方法为核心的执行方法，用户可以在里面自由的实现自己想要的功能。</p>
</li>
<li>
<p><code>getOrder()</code> 指定插件的排序。</p>
</li>
<li>
<p><code>named()</code> 指定插件的名称。</p>
</li>
<li>
<p><code>skip()</code> 在特定的条件下，该插件是否被跳过。</p>
</li>
</ul>
</li>
<li>
<p>注册成Spring的bean，参考如下,或者直接在实现类上加 <code>@Component</code> 注解。</p>
</li>
</ul>
<pre><code class="language-java">    <span class="hljs-meta">@Bean</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> SoulPlugin <span class="hljs-title">a</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> A();
    }
</code></pre>
<h2>匹配流量处理插件</h2>
<ul>
<li>引入如下依赖 :</li>
</ul>
<pre><code class="language-xml"> <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.dromara<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>soul-plugin-base<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>${last.version}<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
</code></pre>
<ul>
<li>
<p>新增一个类A，继承 <code>org.dromara.soul.plugin.base.AbstractSoulPlugin</code></p>
</li>
<li>
<p>以下是参考 ：</p>
</li>
</ul>
<pre><code class="language-java"><span class="hljs-comment">/**
 * This is your custom plugin.
 * He is running in after before plugin, implement your own functionality.
 * extends AbstractSoulPlugin so you must user soul-admin And add related plug-in development.
 *
 * <span class="hljs-doctag">@author</span> xiaoyu(Myth)
 */</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CustomPlugin</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">AbstractSoulPlugin</span> </span>{

    <span class="hljs-comment">/**
     * return plugin order .
     * The same plugin he executes in the same order.
     *
     * <span class="hljs-doctag">@return</span> int
     */</span>
    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">getOrder</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
    }

    <span class="hljs-comment">/**
     * acquire plugin name.
     * return you custom plugin name.
     * It must be the same name as the plug-in you added in the admin background.
     *
     * <span class="hljs-doctag">@return</span> plugin name.
     */</span>
    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">named</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> <span class="hljs-string">"soul"</span>;
    }

    <span class="hljs-comment">/**
     * plugin is execute.
     * Do I need to skip.
     * if you need skip return true.
     *
     * <span class="hljs-doctag">@param</span> exchange the current server exchange
     * <span class="hljs-doctag">@return</span> default false.
     */</span>
    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> Boolean <span class="hljs-title">skip</span><span class="hljs-params">(<span class="hljs-keyword">final</span> ServerWebExchange exchange)</span> </span>{
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">protected</span> Mono&lt;Void&gt; <span class="hljs-title">doExecute</span><span class="hljs-params">(ServerWebExchange exchange, SoulPluginChain chain, SelectorZkDTO selector, RuleZkDTO rule)</span> </span>{
        LOGGER.debug(<span class="hljs-string">".......... function plugin start.............."</span>);
        <span class="hljs-comment">/*
         * Processing after your selector matches the rule.
         * rule.getHandle() is you Customize the json string to be processed.
         * for this example.
         * Convert your custom json string pass to an entity class.
         */</span>
        <span class="hljs-keyword">final</span> String ruleHandle = rule.getHandle();

        <span class="hljs-keyword">final</span> Test test = GsonUtils.getInstance().fromJson(ruleHandle, Test<span class="hljs-class">.<span class="hljs-keyword">class</span>)</span>;

        <span class="hljs-comment">/*
         * Then do your own business processing.
         * The last execution  chain.execute(exchange).
         * Let it continue on the chain until the end.
         */</span>
        System.out.println(test.toString());
        <span class="hljs-keyword">return</span> chain.execute(exchange);
    }
}

</code></pre>
<ul>
<li>
<p>详细讲解 ：</p>
<ul>
<li>
<p>继承该类的插件，插件会进行选择器规则匹配，那如何来设置呢？</p>
</li>
<li>
<p>首先在 <code>soul-admin</code> 后台 --&gt;插件管理中，新增一个插件，注意 名称与 你自定义插件的 <code>named()</code> 方法要一致。</p>
</li>
<li>
<p>重新登陆  <code>soul-admin</code> 后台 ，你会发现在插件列表就多了一个你刚新增的插件，你就可以进行选择器规则匹配</p>
</li>
<li>
<p>在规则中，有个 <code>handler</code> 字段，是你自定义处理数据，在 <code>doExecute()</code> 方法中，通过 <code>final String ruleHandle = rule.getHandle();</code> 获取，然后进行你的操作。</p>
</li>
</ul>
</li>
<li>
<p>注册成Spring的bean，参考如下,或者直接在实现类上加 <code>@Component</code> 注解。</p>
</li>
</ul>
<pre><code class="language-java">    <span class="hljs-meta">@Bean</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> SoulPlugin <span class="hljs-title">a</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> A();
    }
</code></pre>
<h2>订阅你的插件数据，进行自定义的处理</h2>
<ul>
<li>新增一个类A，实现 <code>org.dromara.soul.plugin.base.handler.PluginDataHandler</code></li>
</ul>
<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">PluginDataHandler</span> </span>{

    <span class="hljs-comment">/**
     * Handler plugin.
     *
     * <span class="hljs-doctag">@param</span> pluginData the plugin data
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">default</span> <span class="hljs-keyword">void</span> <span class="hljs-title">handlerPlugin</span><span class="hljs-params">(PluginData pluginData)</span> </span>{
    }

    <span class="hljs-comment">/**
     * Remove plugin.
     *
     * <span class="hljs-doctag">@param</span> pluginData the plugin data
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">default</span> <span class="hljs-keyword">void</span> <span class="hljs-title">removePlugin</span><span class="hljs-params">(PluginData pluginData)</span> </span>{
    }

    <span class="hljs-comment">/**
     * Handler selector.
     *
     * <span class="hljs-doctag">@param</span> selectorData the selector data
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">default</span> <span class="hljs-keyword">void</span> <span class="hljs-title">handlerSelector</span><span class="hljs-params">(SelectorData selectorData)</span> </span>{
    }

    <span class="hljs-comment">/**
     * Remove selector.
     *
     * <span class="hljs-doctag">@param</span> selectorData the selector data
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">default</span> <span class="hljs-keyword">void</span> <span class="hljs-title">removeSelector</span><span class="hljs-params">(SelectorData selectorData)</span> </span>{
    }

    <span class="hljs-comment">/**
     * Handler rule.
     *
     * <span class="hljs-doctag">@param</span> ruleData the rule data
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">default</span> <span class="hljs-keyword">void</span> <span class="hljs-title">handlerRule</span><span class="hljs-params">(RuleData ruleData)</span> </span>{
    }

    <span class="hljs-comment">/**
     * Remove rule.
     *
     * <span class="hljs-doctag">@param</span> ruleData the rule data
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">default</span> <span class="hljs-keyword">void</span> <span class="hljs-title">removeRule</span><span class="hljs-params">(RuleData ruleData)</span> </span>{
    }

    <span class="hljs-comment">/**
     * Plugin named string.
     *
     * <span class="hljs-doctag">@return</span> the string
     */</span>
    <span class="hljs-function">String <span class="hljs-title">pluginNamed</span><span class="hljs-params">()</span></span>;

}
</code></pre>
<ul>
<li>
<p>注意 <code>pluginNamed()</code> 要和你自定义的插件名称相同。</p>
</li>
<li>
<p>注册成Spring的bean，参考如下,或者直接在实现类上加 <code>@Component</code> 注解。</p>
</li>
</ul>
<pre><code class="language-java">    <span class="hljs-meta">@Bean</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> PluginDataHandler <span class="hljs-title">a</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> A();
    }
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/website/img/dromara.png"/><div class="cols-container"><div class="col col-12"><h3>免责声明</h3><p>任何单位或个人转载本网站的所有相关信息，请注明来源。</p></div><div class="col col-6"><dl><dt>文档</dt><dd><a href="/website/zh-cn/docs/soul/soul.html" target="_self">概览</a></dd><dd><a href="/website/zh-cn/docs/soul/soul.html" target="_self">快速开始</a></dd><dd><a href="/website/zh-cn/docs/soul/soul.html" target="_self">开发者指南</a></dd></dl></div><div class="col col-6"><dl><dt>资源</dt><dd><a href="/website/zh-cn/blog/index.html" target="_self">博客</a></dd><dd><a href="/website/zh-cn/community/index.html" target="_self">社区</a></dd></dl></div></div><div class="copyright"><span>Copyright ©2020 xiaoyu@apache.org by xiaoyu</span></div></div></footer></div></div>
	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
	<script>
		window.rootPath = '/website';
  </script>
	<script src="/website/build/documentation.js"></script>
</body>
</html>